package whf.framework.web.tag;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;

import whf.framework.security.UserContext;
import whf.framework.util.BeanUtils;
import whf.framework.util.PermissionUtils;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;
import whf.framework.web.HttpHelper;
import whf.framework.web.WebContextHolder;

/**
 * 显示checkbox列表的tag
 * 并按照权限过滤，典型的可以实现级联授权的情况
 * @author wanghaifeng
 * @create Aug 22, 2006 10:35:20 PM
 * 
 */
public class SelectionListTag extends HtmlTag {
	private String selectionName;
	
	private Object source;
	
	private String valueProperty;
	
	private String textProperty;
	
	private boolean multiSelect;
	
	private String selectionOnclick;
	
	private String selectedValues;
	
	//rowcount和columncount
	//如果指定rowcount优先填充行，行满后扩充columncount
	//如果指定columncount优先填充列，列满后扩充行
	//如果同时指定优先考虑列rowcount，columncount缺省为8
	/**
	 * @property int:columnCount
	 */
	private int colCount = 8;
	
	/**
	 * @property int:rowCount
	 * 如果行数大余此值，自动调整columnCount,如果是0忽略
	 */
	private int rowCount;

	public void setSource(Object dataSource) {
		this.source = dataSource;
	}

	public void setValueProperty(String keyProperty) {
		this.valueProperty = keyProperty;
	}

	public void setSelectionName(String name) {
		this.selectionName = name;
	}

	public void setSelectedValues(String selectedValues) {
		this.selectedValues = selectedValues;
	}

	public void setSelectionOnclick(String selectionOnclick) {
		this.selectionOnclick = selectionOnclick;
	}

	public void setTextProperty(String textProperty) {
		this.textProperty = textProperty;
	}
	
	public void setMultiSelect(boolean multiSelection) {
		this.multiSelect = multiSelection;
	}

	public void setColCount(int maxRowCount) {
		this.colCount = maxRowCount;
	}

	public void setRowCount(int autoAdjustRowCount) {
		this.rowCount = autoAdjustRowCount;
	}

	public void release(){
		this.selectionName = null;
		this.source = null;
		this.valueProperty = null;
		this.textProperty = null;
		this.colCount = 8;
		this.rowCount = 0;
		super.release();
	}
	
	public int doStartTag() throws JspException {
		Object datas = null;
		if(this.source != null){
			if(this.source instanceof String){
				datas = pageContext.getAttribute((String)this.source);
				if(datas == null){
					datas = request().getAttribute((String)this.source);
				}
				if(datas == null){
					datas = request().getSession().getAttribute((String)this.source);
				}
			} else {
				datas = this.source;
			}
		}
		String[] selectedValuesArray = null;
		if(!StringUtils.isEmpty(this.selectedValues)){
			selectedValuesArray = StringUtils.split(this.selectedValues, ";");
		}
		Map<String, String> map = Utils.newHashMap();
		if(!StringUtils.isEmpty(this.selectionOnclick))
			map.put("onclick", this.selectionOnclick);
		//
		if(this.rowCount > 0){
			if(datas instanceof Collection){
				int rowCount = ((Collection)datas).size();
				this.colCount = rowCount / this.rowCount; 
				if(this.colCount * this.rowCount < rowCount ){
					this.colCount ++;
				}
			}
		}
		if(this.colCount == 0) this.colCount = 1;
		int width = (100 - this.colCount) / this.colCount;
		//output
		println(super.getOpenTag("div"));
		println("<table class='whf.selection.table'>");
		try{
			if(datas != null){
				if(datas instanceof Collection){
					Iterator it = ((Collection)datas).iterator();
					Object row = this.nextObject(it);
					while(row != null){
						println("<tr>");
						this.printItem(row, map, selectedValuesArray, width);
						int colCount = 1;
						if(colCount < this.colCount){
							row = this.nextObject(it);
							while(row != null){
								this.printItem(row, map, selectedValuesArray, width);
								colCount ++;
								if(colCount >= this.colCount){
									break;
								}
								row = this.nextObject(it);
							}
							for(int i= colCount; i< this.colCount; i++){
								println("<td>&nbsp;</td><td>&nbsp;</td>");
							}
						}
						println("</tr>");
						row = this.nextObject(it);
					}
				}
			}
		}catch(IOException e){
			throw new JspException(e);
		}
		println("</table>");
		println(super.getCloseTag("div"));
		this.release();
		return SKIP_BODY;
	}
	
	/**
	 * 从数据源Iterator中获取数据，并使用权限过滤
	 * @modify wanghaifeng Jan 25, 2007 1:34:41 PM
	 * @param it
	 * @return
	 */
	private Object nextObject(Iterator it){
		UserContext userContext = WebContextHolder.getWebContext().getUserContext();
		while(it.hasNext()){
			Object row = it.next();
			if(row == null) continue;
			//判定权限，如果没有权限跳过不显示
			if(PermissionUtils.hasPermission(userContext, row)){
				return row;
			} else {
				continue;
			}
		}
		return null;
	}
	
	/**
	 * @modify wanghaifeng Jan 25, 2007 1:14:02 PM
	 * @param row
	 * @param map	事件等html元素
	 * @param selectedValuesArray	选中的哪些列
	 * @param width	显示宽度
	 * @throws JspException
	 * @throws IOException
	 */
	private void printItem(Object row, Map<String, String> map,String[] selectedValuesArray,int width) throws JspException, IOException{
		String value = "";
		String text = "";
		if(row instanceof String){
			String rowString = (String)row;
			String[]ss = StringUtils.split(rowString,";");
			if(ss != null){
				if(ss.length > 0)
					value = ss[0];
				if(ss.length > 1)
					text = ss[1];
			}
		} else {
			value = BeanUtils.getStringProperty(row, valueProperty);
			text = BeanUtils.getStringProperty(row, textProperty);
		}
		if(value == null) value = "";
		if(text == null) text = "";

		map.remove("checked");
		if(selectedValuesArray != null){
			for(String s: selectedValuesArray){
				if(StringUtils.equals(s, value)){
					map.put("checked", null);
				}
			}
		}
		super.println("<td width='1%'>");
		if(this.multiSelect){
			super.printInput("checkbox", this.selectionName, value, map);
		} else {
			super.printInput("radio", this.selectionName, value, map);
		}
		super.println("</td>");
		super.println("<td width='"+width+"%'>").print(text).print("</td>");
	}
}
